package com.example.txttoyy

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.AccessibilityServiceInfo
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.media.audiofx.BassBoost
import android.os.Build
import android.os.Bundle
import android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS
import android.text.TextUtils
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityNodeInfo
import java.lang.reflect.Field
import java.util.*
import java.util.Collections.EMPTY_LIST
import kotlin.collections.ArrayList


@SuppressLint("StaticFieldLeak")
object AccessibilityHelper {
    private val TAG = AccessibilityHelper::class.java.simpleName
    var mService: AccessibilityService? = null

    /**
     * 判断辅助服务是否正在运行
     */
    fun isServiceRunning(service: AccessibilityService?): Boolean {
        if (service == null) {
            return false
        }
        val accessibilityManager =
            service!!.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
        val info = service.serviceInfo ?: return false
        val list =
            accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_GENERIC)
        val iterator: Iterator<AccessibilityServiceInfo> = list.iterator()
        var isConnect = false
        while (iterator.hasNext()) {
            val i = iterator.next()
            if (i.id == info.id) {
                isConnect = true
                break
            }
        }
        return isConnect
    }

    /**
     * 打开辅助服务的设置
     */
    fun openAccessibilityServiceSettings(context: Activity) {
        try {
            val intent = Intent(ACTION_ACCESSIBILITY_SETTINGS)
            context.startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 自动点击按钮
     *
     * @param event
     * @param nodeText 按钮文本
     */
    fun handleEvent(event: AccessibilityEvent, nodeText: String?) {
        val unintall_nodes = event.source.findAccessibilityNodeInfosByText(nodeText)
        if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
            var node: AccessibilityNodeInfo
            for (i in unintall_nodes.indices) {
                node = unintall_nodes[i]
                if (node.className == "android.widget.Button" && node.isEnabled) {
                    node.performAction(AccessibilityNodeInfo.ACTION_CLICK)
                }
            }
        }
    }

    /**
     * 获取text
     */
    fun getNodeText(id: String?): String? {
        val unintall_nodes = mService!!.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
            id!!
        )
        return if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
            unintall_nodes[0].text.toString().trim { it <= ' ' }
        } else null
    }

    /**
     * 获取text
     */
    fun getNodeText(nodeInfo: AccessibilityNodeInfo, id: String?): String? {
        val unintall_nodes = nodeInfo.findAccessibilityNodeInfosByViewId(
            id!!
        )
        return if (unintall_nodes != null && !unintall_nodes.isEmpty()) {
            unintall_nodes[0].text.toString().trim { it <= ' ' }
        } else null
    }

    //通过id查找
    fun findNodeInfosById(
        nodeInfo: AccessibilityNodeInfo?,
        resId: String?
    ): AccessibilityNodeInfo? {
        if (nodeInfo == null) return null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val list = nodeInfo.findAccessibilityNodeInfosByViewId(
                resId!!
            )
            if (list != null && !list.isEmpty()) {
                return list[0]
            }
        }
        return null
    }

    //通过id查找
    fun findNodeInfosById(resId: String?): AccessibilityNodeInfo? {
        if (mService!!.rootInActiveWindow != null) {
            val list = mService!!.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
                resId!!
            )
            if (list != null && !list.isEmpty()) {
                return list[0]
            }
        }
        return null
    }

    //通过id查找
    fun findNodeListInfosById(resId: String?): List<AccessibilityNodeInfo> {
        val result: MutableList<AccessibilityNodeInfo> = ArrayList()
        if (mService!!.rootInActiveWindow != null) {
            val list = mService!!.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
                resId!!
            )
            if (list != null) {
                result.addAll(list)
            }
        }
        return result
    }

    //通过id查找 ,第i个组件
    fun findNodeInfosById(resId: String?, index: Int): AccessibilityNodeInfo? {
        val list = mService!!.rootInActiveWindow.findAccessibilityNodeInfosByViewId(
            resId!!
        )
        return if (list != null && list.size > index) {
            list[index]
        } else null
    }

    //返回指定位置的node
    fun findNodeInfosByIdAndPosition(
        nodeInfo: AccessibilityNodeInfo?,
        resId: String?,
        position: Int
    ): AccessibilityNodeInfo? {
        if (nodeInfo == null) return null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val list = nodeInfo.findAccessibilityNodeInfosByViewId(
                resId!!
            )
            for (i in list.indices) {
                if (i == position) {
                    return list[i]
                }
            }
        }
        return null
    }

    //通过某个文本查找
    fun findNodeInfosByText(
        nodeInfo: AccessibilityNodeInfo?,
        text: String?
    ): AccessibilityNodeInfo? {
        if (nodeInfo == null) return null
        val list = nodeInfo.findAccessibilityNodeInfosByText(text)
        return if (list == null || list.isEmpty()) {
            null
        } else list[0]
    }

    //通过某个文本查找
    fun findNodeInfosByText(text: String?): AccessibilityNodeInfo? {
        if (mService!!.rootInActiveWindow != null) {
            val list = mService!!.rootInActiveWindow.findAccessibilityNodeInfosByText(text)
            return if (list == null || list.isEmpty()) {
                null
            } else list[0]
        }
        return null
    }

    //通过ClassName查找
    fun findNodeInfosByClassName(
        nodeInfo: AccessibilityNodeInfo?,
        className: String
    ): AccessibilityNodeInfo? {
        if (TextUtils.isEmpty(className)) {
            return null
        }
        var i = 0
        while (nodeInfo != null && i < nodeInfo.childCount) {
            val node = nodeInfo.getChild(i)
            if (node != null) {
                if (className == node.className) {
                    return node
                } else if (node.childCount > 0) {
                    findNodeInfosByClassName(node, className)
                }
            }
            i++
        }
        return null
    }

    //通过ClassName查找
    fun findNodeInfoListByClassName(
        nodeInfo: AccessibilityNodeInfo?,
        className: String
    ): List<AccessibilityNodeInfo> {
        if (TextUtils.isEmpty(className)) {
            return EMPTY_LIST as List<AccessibilityNodeInfo>
        }
        val result: MutableList<AccessibilityNodeInfo> = ArrayList()
        var i = 0
        while (nodeInfo != null && i < nodeInfo.childCount) {
            val node = nodeInfo.getChild(i)
            if (node != null && className == node.className) {
                result.add(node)
            }
            i++
        }
        return result
    }

    //通过ClassName查找
    fun findNodeInfosByClassName(className: String): AccessibilityNodeInfo? {
        return findNodeInfosByClassName(mService!!.rootInActiveWindow, className)
    }

    /**
     * 找父组件
     */
    fun findParentNodeInfosByClassName(
        nodeInfo: AccessibilityNodeInfo?,
        className: String
    ): AccessibilityNodeInfo? {
        if (nodeInfo == null) {
            return null
        }
        if (TextUtils.isEmpty(className)) {
            return null
        }
        return if (className == nodeInfo.className) {
            nodeInfo
        } else findParentNodeInfosByClassName(nodeInfo.parent, className)
    }

    private var sSourceNodeField: Field? = null
    fun getSourceNodeId(nodeInfo: AccessibilityNodeInfo?): Long {
        if (sSourceNodeField == null) {
            return -1
        }
        try {
            return sSourceNodeField!!.getLong(nodeInfo)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return -1
    }

    fun getViewIdResourceName(nodeInfo: AccessibilityNodeInfo): String? {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            nodeInfo.viewIdResourceName
        } else null
    }

    //返回HOME界面
    fun performHome(service: AccessibilityService?) {
        if (service == null) {
            return
        }
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_HOME)
    }

    //返回
    fun performBack(service: AccessibilityService?) {
        if (service == null) {
            return
        }
        service.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
    }

    //返回
    fun performBack() {
        //默认使用MainService
        if (mService == null) {
            return
        }
        mService!!.performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK)
    }

    /**
     * 点击事件
     */
    fun performClick(nodeInfo: AccessibilityNodeInfo?) {
        if (nodeInfo == null) {
            return
        }
        if (nodeInfo.isClickable) {
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK)
        } else {
            performClick(nodeInfo.parent)
        }
    }

    /**
     * 点击事件
     */
    fun performClick(id: String?) {
        performClick(findNodeInfosById(id))
    }

    //长按事件
    fun performLongClick(nodeInfo: AccessibilityNodeInfo?) {
        if (nodeInfo == null) {
            return
        }
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_LONG_CLICK)
    }

    //move 事件
    fun performMoveDown(nodeInfo: AccessibilityNodeInfo?) {
        if (nodeInfo == null) {
            return
        }
        nodeInfo.performAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_DOWN.id)
    }

    //ACTION_SCROLL_FORWARD 事件
    fun perform_scroll_forward(nodeInfo: AccessibilityNodeInfo?): Boolean {
        return nodeInfo?.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) ?: false
    }

    //ACTION_SCROLL_BACKWARD 后退事件
    fun perform_scroll_backward(nodeInfo: AccessibilityNodeInfo?): Boolean {
        return nodeInfo?.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) ?: false
    }

    //粘贴
    @TargetApi(18)
    fun performPaste(nodeInfo: AccessibilityNodeInfo?) {
        if (nodeInfo == null) {
            return
        }
        nodeInfo.performAction(AccessibilityNodeInfo.ACTION_PASTE)
    }

    //设置editview text
    @TargetApi(21)
    fun performSetText(nodeInfo: AccessibilityNodeInfo?, text: String?) {
        if (nodeInfo == null) {
            return
        }
        val className = nodeInfo.className
        if ("android.widget.EditText" == className) { //||"android.widget.TextView".equals(className)
            val arguments = Bundle()
            arguments.putCharSequence(
                AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
                text
            )
            nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments)
        }
    }

    init {
        var field: Field? = null
        try {
            field = AccessibilityNodeInfo::class.java.getDeclaredField("mSourceNodeId")
            field.setAccessible(true)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        sSourceNodeField = field
    }
}
